/*
 * File:   vlakna.c
 * Author: FReSH
 *
 * Created on 17. kv�ten 2009, 18:58
 *
 * TVAR zadani - ID:priorita:Instrukce,Instrukce,Instrukce.....
 *
  * CHYBY
 * 1001 - ID neni cislo
 * 1002 - chyby ":" za ID
 * 1003 - Priorita neni cislo
 * 1004 - Chybi ":" za prioritou
 * 1005 - Chybna instrukce - pocatecni pismeno sedi
 * 1006 - intrukce nebyla nalezena
 * 1007 - Spatne zadani instrukce - cas neni cislo
 *

 * 1103 - Priorita nema spravnou hodnotu
 * 1101 - ID je duplicitni!! // TODO udelat kontrolu duplicitnich ID
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 *       Deklarace proměnných
 */



typedef struct blok_instrukci
{
    int instrukce_blok;
    int cas_blok;
    blok_instrukci* dalsi_instrukce;
};

typedef struct vzor_vlakno
{
    int ID_vlakna;
    int priorita_vlakna;
    blok_instrukci* instrukce_vlakna;
    vzor_vlakno* dalsi_vzor;
};

vzor_vlakno* pamet;
int ID;                 // ID vlakna
int priorita;           // priorita vlakna
int cas;                // parametr instrukce (doba trvani nebo cislo vlakna)
int instrukce;          // cislo instrukce

int* adresa;



int p[10];           // pocty vlaken u jednotlivych priorit

int nove_ID = 1;        // citac pro vytvareni novych vlaken

int vytvoreno;          // 1 - pokud je vytvoren zaznam o vlaknu(pridava se do pameti) 0 - musi se vytvorit misto v pameti

char znak;              // pomocna promenna pro nacitani po znacich ze vstupu
int pomoc;              // pomocna promenna typu INT

void chyba(int cislo_chyby) // Vypise kod chyby a ukonci program
{
    printf("\n\nOou, neco se pokazilo :(, kod chyby = %d\n", cislo_chyby);
    if (cislo_chyby < 8000)
    {
        printf("Koncim program..\n\n\n");
        exit(1);
    }
}

void zaloz_vlakna()
{
    printf("Zakladam vlakno \n");
    //TODO udelat vytvoreni vlakna podle pole priorit - 1 -10 - prvni zalozeni vlaken
}

void vytvor_zaznam()
{
/*
    printf("Zapisuji informace o vlaknu a prvni instrukci do pameti...  \n");
    p[priorita-1]++;       // pridava se vlakno priority do pole p
    adresa = (int*) realloc(NULL, 5*sizeof(int));
    *adresa = ID;
    *(adresa + sizeof(int)) = priorita;
    *(adresa + 2*(sizeof(int))) = instrukce;
    *(adresa + 3*(sizeof(int))) = cas;
    *(adresa + 4*(sizeof(int))) = 0;
*/
    pamet = new vzor_vlakno();


// TODO ted zapsat adresu do pole priorit - predtim realokovat pole na velikost p(priorita)+1 (musi se zapsat nula na znameni konce!)

    //TODO pripravit zapis instrukci do pameti (malloc) - zapisuje se ID(int),priorita(int),instrukce(int),cas(int)
    // - nezapomenou na nulu na konci!!
}
void pridej_polozku()
{
   /*
    int prvek = 0;
    int cislo = 6;
    int cykl = 0;

    while ((cislo != 0) || (prvek % 2 != 1))                //počítá kolik je prvků v instrukci
    {
        cislo = *(adresa + prvek*(sizeof(int)));
        prvek++;
        printf("Prvek: %d - cislo: %d\n",prvek,cislo);
    }

    prvek = prvek+2;

    for(cykl = 0;cykl<prvek-2;cykl++)
    {
        cislo = *(adresa + cykl*sizeof(int));
        printf(" %d",cislo);
    }
    printf(" --- puvodni\n");

    adresa = (int*) realloc(adresa, prvek*sizeof(int));

    for(cykl = 0;cykl<prvek;cykl++)
    {
        cislo = *(adresa + cykl*sizeof(int));
        printf(" %d",cislo);
    }
    printf(" --- zvetsena \n");

    *(adresa + (prvek-3)*sizeof(int)) = instrukce;
    *(adresa + (prvek-2)*sizeof(int)) = cas;
    *(adresa + (prvek-1)*sizeof(int)) = 0;

    for(cykl = 0;cykl<prvek;cykl++)
    {
        cislo = *(adresa + cykl*sizeof(int));
        printf(" %d",cislo);
    }
    printf(" --- pridana \n");
*/

}



int zapis_cas()
{
    printf("Nalezen cas po ktery se ma instrukce provadet - %d - %d \n", instrukce, cas);
    if ((instrukce != 4) && (cas == 0)){ return(-1);}
    if (vytvoreno == 0)
    {
        vytvor_zaznam();
        vytvoreno = 1;
    }
    else {pridej_polozku();}
    return(1);
}

void cpu()
{
    printf("Nalezeno cpu (1)   ");
    instrukce = 1;
}

void io()
{
    printf("Nalezeno io (2)    ");
    instrukce = 2;
}

void sleep()
{
    printf("Nalezeno sleep (3)  ");
    instrukce = 3;
}
void create()

{
    printf("Nalezeno create (4)    ");
    instrukce = 4;
}

void zapis_do_pole_vlaken()
{
    printf("Zapisuju vlakno do pameti \n");
}


void nacti_vstup() //TODO nefunguje zapamatovani si feof!!(soubor projde vpohode) - musi se 2x stisknout Ctrl+D???
{
        while (!feof(stdin)) // probíhá načítání ze vstupu, dokud se nedojde na konec souboru - Ctrl+D
    {
        if (vytvoreno == 1)
        {
            printf("SPADNU!!\n");
            free((void*)adresa);
            printf("Mozna dal?\n");
            printf("Mozna dal? 2 \n");
        }
        vytvoreno = 0;                     // priznak dalsiho vlakna
        pomoc = scanf("%d", &ID);          // nacteni ID - prvni udaj v radku - musi byt cislo
        if (pomoc != 1) { chyba(1001); }   // vypise chybu, pokud neni na zacatku cislo

//        printf("Nacteno ID - %d\n", ID);

        scanf("%c", &znak);                // kontroluje, jestli je zde dvojtecka
        if (znak != ':') { chyba(1002); }  // pokud neni dvojtecka, hodi chybu

        pomoc = scanf("%d", &priorita);    // kontroluje, zda je priotrita cislo
        if (pomoc != 1) { chyba(1003); }   // hodi chybu, kdyz neni priorita cislo
        if ((priorita < 1) || (priorita > 10)) { chyba(1103); } // Kontrola priority, jestli je v rozahu

//        printf("Nactena priorita - %d\n", priorita);

        scanf("%c", &znak);
        if (znak != ':') { chyba(1004); }
// Prohledava se seznam instrukci - az do konce radku
        while ((znak != '\n') && (!feof(stdin)))
        {
            scanf("%c", &znak);
// --------------- Roztrideni podle prvnich znaku na CPU IO SLEEP CREATE -----------------------------
            while ((znak != '-') && (znak != ' '))
            {
                if ((znak != 's') && (znak != 'c') && (znak != 'i')) {(chyba(1006));}
                if (znak == 'c')
                {
                    scanf("%c", &znak);
                    if (znak == 'p')
                    {
                       scanf("%c", &znak);
                       if (znak == 'u')
                       {
                           cpu();
                       }
                       else {(chyba(1005));}
                    }
                    else
                    {
                        if (znak == 'r' )
                        {
                            scanf("%c", &znak);
                            if (znak == 'e' )
                            {
                                scanf("%c", &znak);
                                if (znak == 'a' )
                                {
                                    scanf("%c", &znak);
                                    if (znak == 't' )
                                    {
                                        scanf("%c", &znak);
                                        if (znak == 'e' )
                                        {
                                            create();
                                        }
                                        else {(chyba(1005));}
                                    }
                                    else {(chyba(1005));}
                                }
                                else {(chyba(1005));}
                            }
                            else {(chyba(1005));}
                        }
                        else {chyba(1005);}
                    }
                }
                if (znak == 'i')
                {
                    scanf("%c", &znak);
                    if (znak == 'o')
                    {
                        io();
                    }
                    else {(chyba(1005));}
                }
                if (znak == 's')
                {
                    scanf("%c", &znak);
                    if (znak == 'l')
                    {
                        scanf("%c", &znak);
                        if (znak == 'e')
                        {
                            scanf("%c", &znak);
                            if (znak == 'e')
                            {
                                scanf("%c", &znak);
                                if (znak == 'p')
                                {
                                    sleep();
                                }
                                else {(chyba(1005));}
                            }
                            else {(chyba(1005));}
                        }
                        else {(chyba(1005));}
                    }
                    else {(chyba(1005));}
                }
                scanf("%c", &znak);
            }
//            printf("Rozpoznana instrukce, jdu na casove kvantum/cislo vlakna - %d\n", instrukce);
// +++++++++++++++ Roztrideni podle prvnich znaku na CPU IO SLEEP CREATE +++++++++++++++++++++++++++++
            cas = 0;
            while ((znak != '\n') && (znak != ',') && (!feof(stdin)))
            {
                scanf("%c", &znak);
                if ((znak > 57) || (znak < 48))
                {
                    if ((znak != '\n') && (!feof(stdin)) && (znak != ',')){chyba(1007);}
                }
                if ((znak != '\n') && (!feof(stdin)) && (znak != ','))
                {
                    cas = 10*cas + (znak-48);
                }
            }
            if (zapis_cas() == -1) {chyba(8001);};
            zapis_do_pole_vlaken();
        }
    }
}

int main(int argc, char** argv)
{
    printf("Vitej v programu vlakna - semestralni prace z OSY, vytvoril Michal Zima \n\n\n");
    printf("Zadej potrebne parametry vlaken ve tvaru - ID:Priorita:Instrukce1,Instrukce2,Instrukce3,... \n");

    nacti_vstup(); // postupne nacitani vsech radku vlaken
    printf("Hotovo - nacteno vporadku!!\n");

    return (EXIT_SUCCESS);
}

